package com.huazheng.miaosha.web.service.impl;

import com.huazheng.miaosha.web.constant.ErrorEnum;
import com.huazheng.miaosha.web.dao.StockDao;
import com.huazheng.miaosha.web.entity.StockEntity;
import com.huazheng.miaosha.web.entity.StockOrderEntity;
import com.huazheng.miaosha.web.service.OrderService;
import com.huazheng.miaosha.web.service.StockOrderService;
import com.huazheng.miaosha.web.service.StockService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author: zhanghzi
 * @Email: zhanghzi@dcits.com
 * @Date: 2021/1/23 20:01
 * Description: TODO
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private StockService stockService;

    @Resource
    private StockOrderService stockOrderService;

    @Resource
    private StockDao stockDao;

    @Override
    public int createOrder(int sid) {

        //1.校验库存
        StockEntity stock = checkStockNum(sid);
        //2.扣减库存
        decreaseStock(stock);

        //3.生成订单
        int order = doCreateOrder(stock);
        return order;
    }

    @Override
    public int createOrderWithOptisLock(int sid) {
        StockEntity stockEntity = checkStockNum(sid);

        updateStock(stockEntity);
        int order = doCreateOrder(stockEntity);

        return order;
    }

    /*/**
      * @Description 通过乐观锁更新库存，防止超卖
      * @author  zhanghuazheng
      * @Date    2021/1/24 0:05
      * @param   [stockEntity]
      * @return  void
      **/
    private void updateStock(StockEntity stockEntity) {
        int i = stockDao.updateByOptimistic(stockEntity);
        if(i!=1){
            throw new RuntimeException(ErrorEnum.UPDATE_STOCK_FAIL.toString());
        }
    }

    private int doCreateOrder(StockEntity stock) {
        StockOrderEntity stockOrder = new StockOrderEntity();
        stockOrder.setSid(stock.getId());
        stockOrder.setName(stock.getName());
        int result = stockOrderService.insertSelective(stockOrder);
        if(result!=1){
            throw new RuntimeException(ErrorEnum.CREATE_ORDER_FAIL.toString());
        }

        return result;

    }

    /*/**
      * @Description 扣减库存
      * @author  zhanghuazheng
      * @Date     20:48
      * @param   [stock]
      * @return  void
      **/
    private void decreaseStock(StockEntity stock) {
        stock.setSale(stock.getSale()+1);
        stockDao.updateByPrimaryKey(stock);

    }

    /*/**
      * @Description //检查库存剩余商品数量
      * @author  zhanghuazheng
      * @Date    2021/1/23 20:09
      * @param   [sid]
      * @return  boolean
      **/
    private StockEntity checkStockNum(int sid){
        StockEntity stock = stockService.findStockNum(sid);

        if(stock.getSale().equals(stock.getCount())){
            throw new RuntimeException(ErrorEnum.STOCK_ZERO.toString());
        }
        return stock;
    }

}
